<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Language" content="en-us" />
  <meta name="description" content="SvgC examples" />
   <link href="prettify.css" media="screen" rel="stylesheet" type="text/css" />
   <link href="style.css"    media="screen" rel="stylesheet" type="text/css" />
  <script type="text/javascript" src="../js/svg_c.js"></script>
  <script type="text/javascript" src="prettify.js"></script>
  <title>SvgC - Transformations</title>
</head>
<body onload="prettyPrint();">
<div id="container">
<h1>3. Transformations</h1>

<h2> Transformation functions</h2>
Each svgC instance stores a transformation matrix that is assigned to every created element.

<h3>orgin ()</h3>
Resets the transformation matrix

<h3>setMatrix (m)</h3>
Sets the transformation matrix
<ul>
  <li><strong>m</strong> - new transformation matrix</li>
</ul>

<h3>translate (dx, dy)</h3>
Applies translation on transformation matrix
<ul>
  <li><strong>dx</strong> - x-axis coordinate of displacement</li>
  <li><strong>dy</strong> - y-axis coordinate of displacement</li>
</ul>
Example:
<table>
<tr>
<td>
<div id="example_trans">
  <script type="text/javascript">
//<![CDATA[
var c = new SvgC("example_trans", 200, 200);
c.translate(100, 100);
for (var i=0; i<60; i++) {
  var a = i*Math.PI/10;
  var r = 30 + 2*a;
  var x = r*Math.cos(a);
  var y = r*Math.sin(a);
  var k = c.rgb(255, 200-i*3, 10);
  c.circle(x, y, 4, {fill:k});
}
//]]>
  </script>
</div>
</td>
<td>
  <pre class="prettyprint">
var c = new SvgC("example_trans", 200, 200);
c.translate(100, 100);
for (var i=0; i&lt;60; i++) {
  var a = i*Math.PI/10;
  var r = 30 + 2*a;
  var x = r*Math.cos(a);
  var y = r*Math.sin(a);
  var k = c.rgb(255, 200-i*3, 10);
  c.circle(x, y, 4, {fill:k});
}
  </pre>
</td>
</tr>
</table>

<h3>scale (sx, sy)</h3>
Applies scaling on transformation matrix
<ul>
  <li><strong>sx</strong> - x-axis scale factor</li>
  <li><strong>sy</strong> - y-axis scale factor [optional]</li>
</ul>
Example:
<table>
<tr>
<td>
<div id="example_scale">
  <script type="text/javascript">
//<![CDATA[
var c = new SvgC("example_scale", 200, 200);
c.brush("text", {fill:"white", "text-anchor":"middle"});
c.translate(100, 180);
for (var i=1; i<10; i++) {
    var k = c.rgb(255, i*20, 10);
    c.scale(1/Math.log(i+1.5));
    c.circle(0, -60, 60, {fill:k});
    c.text(0, -145, i.toString());
}
//]]>
  </script>
</div>
</td>
<td>
  <pre class="prettyprint">
var c = new SvgC("example_scale", 200, 200);
c.brush("text", {fill:"white", "text-anchor":"middle"});
c.translate(100, 180);
for (var i=1; i&lt;10; i++) {
    var k = c.rgb(255, i*20, 10);
    c.scale(1/Math.log(i+1.5));
    c.circle(0, -60, 60, {fill:k});
    c.text(0, -145, i.toString());
}
  </pre>
</td>
</tr>
</table>

<h3>rotate (angle, cx, cy)</h3>
Applies rotation on transformation matrix
<ul>
  <li><strong>angle</strong> - rotation angle</li>
  <li><strong>rx</strong> - x-axis coordinate of rotation center</li>
  <li><strong>ry</strong> - y-axis coordinate of rotation center</li>
</ul>
Example:
<table>
<tr>
<td>
<div id="example_rotate">
  <script type="text/javascript">
//<![CDATA[
var c = new SvgC("example_rotate", 200, 200);
c.defs(function (c, d) {
  c.attrs["path"] = {"stroke-width":"4px", fill:"none"};
  c.path("#fx", "m 3,3 c 0,-8 -15,-13 -15,-13 l 0,26 c 0,8 15,13 15,13 z");
});

c.translate(100, 100);
c.g("#sun", function (c, g) {
  c.use(0, 0, "#fx");
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#0aa54a"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#4996ce"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#772e8a"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#ff0000"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#ef8a1e"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#ffcc00"});
});
//]]>
</script>
</div>
</td>
<td>
  <pre class="prettyprint">
var c = new SvgC("example_rotate", 200, 200);
c.defs(function (c, d) {
  c.attrs["path"] = {"stroke-width":"4px", fill:"none"};
  c.path("#fx", "m 3,3 c 0,-8 -15,-13 -15,-13 l 0,26 c 0,8 15,13 15,13 z");
});

c.translate(100, 100);
c.g("#sun", function (c, g) {
  c.use(0, 0, "#fx");
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#0aa54a"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#4996ce"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#772e8a"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#ff0000"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#ef8a1e"});
  c.rotate(60, -15, -13).use(0, 0, "#fx", {stroke:"#ffcc00"});
});
  </pre>
</td>
</tr>
</table>

<h3>skewX (angle)</h3>
Applies x-axis skew operation on transformation matrix
<ul>
  <li><strong>angle</strong> - skew angle</li>
</ul>

<h3>skewY (angle)</h3>
Applies y-axis skew operation on transformation matrix
<ul>
  <li><strong>angle</strong> - skew angle</li>
</ul>

<h3>flipX ()</h3>
Applies x-axis flip operation on transformation matrix

<h3>flipY ()</h3>
Applies x-axis flip operation on transformation matrix
<table>
<tr>
<td>
<div id="example_flip">
  <script type="text/javascript">
//<![CDATA[
var c = new SvgC("example_flip", 200, 200);
  c.defs(function (c, d) {
  c.path("#leaf", "m -5,-5 c 0,0 -56,16 -48,-48 64,-8 48,48 48,48 z");
});
c.translate(100,100);
c.use(0, 0,"#leaf", {fill:"#44aa00"});
c.flipX().use(0, 0,"#leaf", {fill:"#ff7f2a"});
c.flipY().use(0, 0,"#leaf", {fill:"#0066ff"});
c.flipX().use(0, 0,"#leaf", {fill:"#d40000"});
c.orgin().translate(100,100).scale(0.5);
c.use(0, 0,"#leaf", {fill:"#c6e9af"});
c.flipX().use(0, 0,"#leaf", {fill:"#ffccaa"});
c.flipY().use(0, 0,"#leaf", {fill:"#aaccff"});
c.flipX().use(0, 0,"#leaf", {fill:"#ffaaaa"});
//]]>
  </script>
</div>
</td>
<td>
  <pre class="prettyprint">
var c = new SvgC("example_flip", 200, 200);
  c.defs(function (c, d) {
  c.path("#leaf", "m -5,-5 c 0,0 -56,16 -48,-48 64,-8 48,48 48,48 z");
});
c.translate(100,100);
c.use(0, 0,"#leaf", {fill:"#44aa00"});
c.flipX().use(0, 0,"#leaf", {fill:"#ff7f2a"});
c.flipY().use(0, 0,"#leaf", {fill:"#0066ff"});
c.flipX().use(0, 0,"#leaf", {fill:"#d40000"});
c.orgin().translate(100,100).scale(0.5);
c.use(0, 0,"#leaf", {fill:"#c6e9af"});
c.flipX().use(0, 0,"#leaf", {fill:"#ffccaa"});
c.flipY().use(0, 0,"#leaf", {fill:"#aaccff"});
c.flipX().use(0, 0,"#leaf", {fill:"#ffaaaa"});
  </pre>
</td>
</tr>
</table>

<h2>Multiple transformations</h2>
Because all transformation functions return svgC instance, functions call can by cascaded. 
<table>
<tr>
<td>
<div id="example_multi">
  <script type="text/javascript">
//<![CDATA[
var c = new SvgC("example_multi", 200, 200);
var p = ["M", -30, 0, "L"];
c.translate(100, 100).scale(2).flipY();
for (var x=-30; x<30; x+=0.5) {
  p.push(x, x*Math.sin(0.7*x));
}
c.path(p, {fill:"none", stroke:"red"});
//]]>
</script>
</div>
</td>
<td>
  <pre class="prettyprint">
var c = new SvgC("example_multi", 200, 200);
var p = ["M", -30, 0, "L"];
c.translate(100, 100).scale(2).flipY();
for (var x=-30; x&lt;30; x+=0.5) {
  p.push(x, x*Math.sin(0.7*x));
}
c.path(p, {fill:"none", stroke:"red"});
  </pre>
</td>
</tr>
</table>
<h2>Transformation by attribute</h2>
Another way to apply transformation is by using SVG transform attribute, either in brush definition or directly as shape attribute.
<table>
<tr>
<td>
<div id="example_trans_attr">
  <script type="text/javascript">
//<![CDATA[
var c = new SvgC("example_trans_attr", 200, 200);
var t = "Transform via\nattribute on\ntext element";
c.brushes({
  "path": {stroke:"brown", fill:"none", "stroke-width":"2px"},
  "text": {stroke:"gray", transform:"rotate(-7) translate(28, 100)"}
});
c.text(0, 0, t);
c.path("M 150,150 l -15,-70 -100,10 5,75 55,-7 10,15 -2,-16 z");
//]]>
</script>
</div>
</td>
<td>
  <pre class="prettyprint">
var c = new SvgC("example_trans_attr", 200, 200);
var t = "Transform via\nattribute on\ntext element";
c.brushes({
  "path": {stroke:"brown", fill:"none", "stroke-width":"2px"},
  "text": {stroke:"gray", transform:"rotate(-7) translate(28, 100)"}
});
c.text(0, 0, t);
c.path("M 150,150 l -15,-70 -100,10 5,75 55,-7 10,15 -2,-16 z");
  </pre>
</td>
</tr>
</table>
</div>
</body>
</html>